﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace _3D_Game2
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        public Camera camera { get; protected set; }
        ModelManager modelManager;
        public Random rnd { get; protected set; }
        //font to display text
        SpriteFont font;
        String numberofmodels = "0";
        float shotSpeed = 5.5f;
        int shotDelay = 300;
        int shotCountdown = 0;






        public Game1()
        {
            rnd = new Random();
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 768;
            #if !DEBUG
            graphics.IsFullScreen = true;
            #endif
        }
        private void DrawText()
        {
            numberofmodels = modelManager.GetModelPosition().ToString();
            spriteBatch.DrawString(font, "Model Position X:" + modelManager.GetModelPosition().X.ToString()
                + " Y:" + modelManager.GetModelPosition().Y.ToString()
                + " Z:" + modelManager.GetModelPosition().Z.ToString()
                , new Vector2(20, 45), Color.White);

            spriteBatch.DrawString(font, "Camera Position X: " + camera.getCameraPosition().X.ToString()
                + " Camera Y: " + camera.getCameraPosition().Y.ToString() +
            " Camera Z: " + camera.getCameraPosition().Z.ToString()
            , new Vector2(20, 65), Color.Bisque);
            
            spriteBatch.DrawString(font, "Camera Direction X: " + camera.GetCameraDirection.X.ToString()
                + "  Y: " + camera.GetCameraDirection.Y.ToString() +
            "  Z: " + camera.GetCameraDirection.Z.ToString()
            , new Vector2(20, 85), Color.Orange);

            spriteBatch.DrawString(font, "Camera Up Direction X: " + camera.getCameraUpDirection().X.ToString()
              + "  Y: " + camera.getCameraUpDirection().Y.ToString() +
          "  Z: " + camera.getCameraUpDirection().Z.ToString()
          , new Vector2(20, 105), Color.OrangeRed);

            spriteBatch.DrawString(font, "Shots position  X: " + modelManager.GetShotPosition().X.ToString()
             + "  Y: " + modelManager.GetShotPosition().Y.ToString() +
         "  Z: " + modelManager.GetShotPosition().Z.ToString()
         , new Vector2(20, 155), Color.Olive);
            spriteBatch.DrawString(font, "Kobala position  X: " + modelManager.GetKobalaPosition().X.ToString()
            + "  Y: " + modelManager.GetKobalaPosition().Y.ToString() +
        "  Z: " + modelManager.GetKobalaPosition().Z.ToString()
        , new Vector2(20, 170), Color.Olive);
            spriteBatch.DrawString(font, "Kobala Direction  X: " + modelManager.GetKobalaDirection().X.ToString()
           + "  Y: " + modelManager.GetKobalaDirection().Y.ToString() +
       "  Z: " + modelManager.GetKobalaDirection().Z.ToString()
       , new Vector2(20, 200), Color.Olive);


        }
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // Initialize camera
            camera = new Camera(this, new Vector3(0f, 0f, 1000.0f),
                 new Vector3(0,0,-10f), Vector3.Up);
            Components.Add(camera);

            modelManager = new ModelManager(this);
            Components.Add(modelManager);

            
            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            

            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            //load my fonts
            font = Content.Load<SpriteFont>(@"Fonts\Myfont1");
            
            
        }
       
        protected void FireShots(GameTime gameTime)
            {
                if (shotCountdown <= 0)
                    {
                        // Did player press space bar or left mouse button?
                        if (Keyboard.GetState( ).IsKeyDown(Keys.Space) )
                            {
                                //direction = new Vector3(0, 0, -50);    
                            // Add a shot to the model manager
                            Vector3 shotDirection = modelManager.GetKobalaDirection();
                            Vector3 shotposition = modelManager.GetKobalaPosition();
                                //shotDirection.Z += shotSpeed;
                            //modelManager.AddShot(
                            //    //camera.cameraPosition + new Vector3(0, 0, 0),
                            //    //new Vector3(0, 0, 2) * shotSpeed);
                            //    modelManager.GetKobalaPosition(),
                            //    shotDirection);
                                //modelManager.AddShot(shotposition,shotDirection);
                                modelManager.AddShot(shotposition,shotDirection);

                                // Reset the shot countdown
                                shotCountdown = shotDelay;             
                               // modelManager.setShotPosition(camera.cameraPosition + new Vector3(0, 0, 0));
                            }   


                    }
                else
                    shotCountdown -= gameTime.ElapsedGameTime.Milliseconds;
            }






        Vector3 DirectionToTravel(bool rotationVecIsInRadians, Vector3 rotationVec)//rotation vec must not be normalized at this point
        {
            Vector3 result;

            if (!rotationVecIsInRadians)
            {
                rotationVec *= MathHelper.Pi / 180f;
            }

            float angle = rotationVec.Length();
            rotationVec /= angle; //normalizes rotation vec

            result = Matrix.CreateFromAxisAngle(rotationVec, angle).Forward;

            return result;
        }    
                            
        
        
        
        
        
        
        
        
        
        
        
        
        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                this.Exit();

            // See if the player has fired a shot
            FireShots(gameTime);

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            // TODO: Add your drawing code here
            spriteBatch.Begin();
            DrawText();
            
            
            
            
            
            
            spriteBatch.End();

            GraphicsDevice.BlendState = BlendState.Opaque;
            GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

            base.Draw(gameTime);
        }
    }
}
